(*$U-*)
    
{ This is an unpublished work copyright by The Regents of the University
  of California.  This item is the property of SofTech MicroSystems Inc.,
  and it may be used, copied, or distributed only as permitted in a 
  written license from that company.}

PROGRAM PASCALSYSTEM;

(************************************************)
(*                                              *)
(*    UCSD PASCAL OPERATING SYSTEM              *)
(*                                              *)
(*    RELEASE LEVEL:  I.3   AUGUST, 1977        *)
(*                    I.4   JANUARY, 1978       *)
(*                    I.5   SEPTEMBER, 1978     *)
(*                    II.0  FEBRUARY, 1978 BD   *)
(*                                              *)
(*    WRITTEN BY ROGER T. SUMNER                *)
(*    WINTER 1977                               *)
(*                                              *)
(*    INSTITUTE FOR INFORMATION SYSTEMS         *)
(*    UC SAN DIEGO, LA JOLLA, CA                *)
(*                                              *)
(*    KENNETH L. BOWLES, DIRECTOR               *)
(*                                              *)
(************************************************)

CONST
     MMAXINT = 32767;   (*MAXIMUM INTEGER VALUE*)
     MAXUNIT = 12;      (*MAXIMUM PHYSICAL UNIT # FOR UREAD*)
     MAXDIR = 77;       (*MAX NUMBER OF ENTRIES IN A DIRECTORY*)
     VIDLENG = 7;       (*NUMBER OF CHARS IN A VOLUME ID*)
     TIDLENG = 15;      (*NUMBER OF CHARS IN TITLE ID*)
     MAXSEG = 15;       (*MAX CODE SEGMENT NUMBER*)
     FBLKSIZE = 512;    (*STANDARD DISK BLOCK LENGTH*)
     DIRBLK = 2;        (*DISK ADDR OF DIRECTORY*)
     AGELIMIT = 300;    (*MAX AGE FOR GDIRP...IN TICKS*)
     EOL = 13;          (*END-OF-LINE...ASCII CR*)
     DLE = 16;          (*BLANK COMPRESSION CODE*)
     NAME_LEN = 23;     {Length of CONCAT(VIDLENG,':',TIDLENG)}
     FILL_LEN = 11;     {Maximum # of nulls in FILLER}

TYPE

     IORSLTWD = (INOERROR,IBADBLOCK,IBADUNIT,IBADMODE,ITIMEOUT,
                 ILOSTUNIT,ILOSTFILE,IBADTITLE,INOROOM,INOUNIT,
                 INOFILE,IDUPFILE,INOTCLOSED,INOTOPEN,IBADFORMAT,
                 ISTRGOVFL);

                                        (*COMMAND STATES...SEE GETCMD*)

     CMDSTATE = (HALTINIT,DEBUGCALL,
                 UPROGNOU,UPROGUOK,SYSPROG,
                 COMPONLY,COMPANDGO,COMPDEBUG,
                 LINKANDGO,LINKDEBUG);
     
                                        (*CODE FILES USED IN GETCMD*)
                                        
     SYSFILE = (ASSMBLER,COMPILER,EDITOR,FILER,LINKER);

                                        (*ARCHIVAL INFO...THE DATE*)

     DATEREC = PACKED RECORD
                 MONTH: 0..12;          (*0 IMPLIES DATE NOT MEANINGFUL*)
                 DAY: 0..31;            (*DAY OF MONTH*)
                 YEAR: 0..100           (*100 IS TEMP DISK FLAG*)
               END (*DATEREC*) ;

                                        (*VOLUME TABLES*)
     UNITNUM = 0..MAXUNIT;
     VID = STRING[VIDLENG];

                                        (*DISK DIRECTORIES*)
     DIRRANGE = 0..MAXDIR;
     TID = STRING[TIDLENG];
     FULL_ID = STRING[NAME_LEN];

     FILE_TABLE = ARRAY [SYSFILE] OF FULL_ID;
     
     FILEKIND = (UNTYPEDFILE,XDSKFILE,CODEFILE,TEXTFILE,
                 INFOFILE,DATAFILE,GRAFFILE,FOTOFILE,SECUREDIR);

     DIRENTRY = PACKED RECORD
                  DFIRSTBLK: INTEGER;   (*FIRST PHYSICAL DISK ADDR*)
                  DLASTBLK: INTEGER;    (*POINTS AT BLOCK FOLLOWING*)
                  CASE DFKIND: FILEKIND OF
                    SECUREDIR,
                    UNTYPEDFILE: (*ONLY IN DIR[0]...VOLUME INFO*)
                       (FILLER1 : 0..2048; {for downward compatibility,13 bits}
                        DVID: VID;              (*NAME OF DISK VOLUME*)
                        DEOVBLK: INTEGER;       (*LASTBLK OF VOLUME*)
                        DNUMFILES: DIRRANGE;    (*NUM FILES IN DIR*)
                        DLOADTIME: INTEGER;     (*TIME OF LAST ACCESS*)
                        DLASTBOOT: DATEREC);    (*MOST RECENT DATE SETTING*)
                    XDSKFILE,CODEFILE,TEXTFILE,INFOFILE,
                    DATAFILE,GRAFFILE,FOTOFILE:
                       (FILLER2 : 0..1024; {for downward compatibility}
                        STATUS : BOOLEAN;        {for FILER wildcards}
                        DTID: TID;              (*TITLE OF FILE*)
                        DLASTBYTE: 1..FBLKSIZE; (*NUM BYTES IN LAST BLOCK*)
                        DACCESS: DATEREC)       (*LAST MODIFICATION DATE*)
                END (*DIRENTRY*) ;

     DIRP = ^DIRECTORY;

     DIRECTORY = ARRAY [DIRRANGE] OF DIRENTRY;

                                        (*FILE INFORMATION*)

     CLOSETYPE = (CNORMAL,CLOCK,CPURGE,CCRUNCH);
     WINDOWP = ^WINDOW;
     WINDOW = PACKED ARRAY [0..0] OF CHAR;
     FIBP = ^FIB;

     FIB = RECORD
             FWINDOW: WINDOWP;  (*USER WINDOW...F^, USED BY GET-PUT*)
             FEOF,FEOLN: BOOLEAN;
             FSTATE: (FJANDW,FNEEDCHAR,FGOTCHAR);
             FRECSIZE: INTEGER; (*IN BYTES...0=>BLOCKFILE, 1=>CHARFILE*)
             CASE FISOPEN: BOOLEAN OF
               TRUE: (FISBLKD: BOOLEAN; (*FILE IS ON BLOCK DEVICE*)
                      FUNIT: UNITNUM;   (*PHYSICAL UNIT #*)
                      FVID: VID;        (*VOLUME NAME*)
                      FREPTCNT,         (* # TIMES F^ VALID W/O GET*)
                      FNXTBLK,          (*NEXT REL BLOCK TO IO*)
                      FMAXBLK: INTEGER; (*MAX REL BLOCK ACCESSED*)
                      FMODIFIED:BOOLEAN;(*PLEASE SET NEW DATE IN CLOSE*)
                      FHEADER: DIRENTRY;(*COPY OF DISK DIR ENTRY*)
                      CASE FSOFTBUF: BOOLEAN OF (*DISK GET-PUT STUFF*)
                        TRUE: (FNXTBYTE,FMAXBYTE: INTEGER;
                               FBUFCHNGD: BOOLEAN;
                               FBUFFER: PACKED ARRAY [0..FBLKSIZE] OF CHAR))
           END (*FIB*) ;

                                        (*USER WORKFILE STUFF*)

     INFOREC = RECORD
                 SYMFIBP,CODEFIBP: FIBP;        (*WORKFILES FOR SCRATCH*)
                 ERRSYM,ERRBLK,ERRNUM: INTEGER; (*ERROR STUFF IN EDIT*)
                 SLOWTERM,STUPID: BOOLEAN;      (*STUDENT PROGRAMMER ID!!*)
                 ALTMODE: CHAR;                 (*WASHOUT CHAR FOR COMPILER*)
                 GOTSYM,GOTCODE: BOOLEAN;       (*TITLES ARE MEANINGFUL*)
                 WORKVID,SYMVID,CODEVID: VID;   (*PERM&CUR WORKFILE VOLUMES*)
                 WORKTID,SYMTID,CODETID: TID    (*PERM&CUR WORKFILES TITLE*)
               END (*INFOREC*) ;

                                        (*CODE SEGMENT LAYOUTS*)

     SEGRANGE = 0..MAXSEG;
     SEGDESC = RECORD
                 DISKADDR: INTEGER;     (*REL BLK IN CODE...ABS IN SYSCOM^*)
                 CODELENG: INTEGER      (*# BYTES TO READ IN*)
               END (*SEGDESC*) ;

                                        (*DEBUGGER STUFF*)

     BYTERANGE = 0..255;
     TRICKARRAY = RECORD        {Memory diddling for execerror}
                    CASE BOOLEAN OF
                      TRUE : (WORD : ARRAY [0..0] OF INTEGER); 
                      FALSE : (BYTE : PACKED ARRAY [0..0] OF BYTERANGE)
                    END;
     MSCWP = ^ MSCW;            (*MARK STACK RECORD POINTER*)
     MSCW = RECORD
              STATLINK: MSCWP;  (*POINTER TO PARENT MSCW*)
              DYNLINK: MSCWP;   (*POINTER TO CALLER'S MSCW*)
              MSSEG,MSJTAB: ^TRICKARRAY;
              MSIPC: INTEGER;
              LOCALDATA: TRICKARRAY
            END (*MSCW*) ;

                                        (*SYSTEM COMMUNICATION AREA*)
                                        (*SEE INTERPRETERS...NOTE  *)
                                        (*THAT WE ASSUME BACKWARD  *)
                                        (*FIELD ALLOCATION IS DONE *)
     SYSCOMREC = RECORD
                   IORSLT: IORSLTWD;    (*RESULT OF LAST IO CALL*)
                   XEQERR: INTEGER;     (*REASON FOR EXECERROR CALL*)
                   SYSUNIT: UNITNUM;    (*PHYSICAL UNIT OF BOOTLOAD*)
                   BUGSTATE: INTEGER;   (*DEBUGGER INFO*)
                   GDIRP: DIRP;         (*GLOBAL DIR POINTER,SEE VOLSEARCH*)
                   LASTMP,STKBASE,BOMBP: MSCWP;
                   MEMTOP,SEG,JTAB: INTEGER;
                   BOMBIPC: INTEGER;    (*WHERE XEQERR BLOWUP WAS*)
                   HLTLINE: INTEGER;    (*MORE DEBUGGER STUFF*)
                   BRKPTS: ARRAY [0..3] OF INTEGER;
                   RETRIES: INTEGER;    (*DRIVERS PUT RETRY COUNTS*)
                   EXPANSION: ARRAY [0..8] OF INTEGER;
                   HIGHTIME,LOWTIME: INTEGER;
                   MISCINFO: PACKED RECORD
                               NOBREAK,STUPID,SLOWTERM,
                               HASXYCRT,HASLCCRT,HAS8510A,HASCLOCK: BOOLEAN;
                               USERKIND:(NORMAL, AQUIZ, BOOKER, PQUIZ);
                               IS_FLIPT : BOOLEAN
                             END;
                   CRTTYPE: INTEGER;
                   CRTCTRL: PACKED RECORD
                              RLF,NDFS,ERASEEOL,ERASEEOS,HOME,ESCAPE: CHAR;
                              BACKSPACE: CHAR;
                              FILLCOUNT: 0..255;
                              CLEARSCREEN, CLEARLINE: CHAR;
                              PREFIXED: PACKED ARRAY [0..8] OF BOOLEAN
                            END;
                   CRTINFO: PACKED RECORD
                              WIDTH,HEIGHT: INTEGER;
                              RIGHT,LEFT,DOWN,UP: CHAR;
                              BADCH,CHARDEL,STOP,BREAK,FLUSH,EOF: CHAR;
                              ALTMODE,LINEDEL: CHAR;
                              BACKSPACE,ETX,PREFIX: CHAR;
                              PREFIXED: PACKED ARRAY [0..13] OF BOOLEAN
                            END;
                   SEGTABLE: ARRAY [SEGRANGE] OF
                               RECORD
                                 CODEUNIT: UNITNUM;
                                 CODEDESC: SEGDESC
                               END
                 END (*SYSCOM*);

     MISCINFOREC = RECORD
                     MSYSCOM: SYSCOMREC
                   END;

VAR
    SYSCOM: ^SYSCOMREC;                 (*MAGIC PARAM...SET UP IN BOOT*)
    GFILES: ARRAY [0..5] OF FIBP;       (*GLOBAL FILES, 0=INPUT, 1=OUTPUT*)
    USERINFO: INFOREC;                  (*WORK STUFF FOR COMPILER ETC*)
    EMPTYHEAP: ^INTEGER;                (*HEAP MARK FOR MEM MANAGING*)
    INPUTFIB,OUTPUTFIB,                 (*CONSOLE FILES...GFILES ARE COPIES*)
    SYSTERM,SWAPFIB: FIBP;              (*CONTROL AND SWAPSPACE FILES*)
    SYVID,DKVID: VID;                   (*SYSUNIT VOLID & DEFAULT VOLID*)
    THEDATE: DATEREC;                   (*TODAY...SET IN FILER OR SIGN ON*)
    DEBUGINFO: ^INTEGER;                (*DEBUGGERS GLOBAL INFO WHILE RUNIN*)
    STATE: CMDSTATE;                    (*FOR GETCOMMAND*)
    PL: STRING;                         (*PROMPTLINE STRING...SEE PROMPT*)
    IPOT: ARRAY [0..4] OF INTEGER;      (*INTEGER POWERS OF TEN*)
    FILLER: STRING[FILL_LEN];           (*NULLS FOR CARRIAGE DELAY*)
    DIGITS: SET OF '0'..'9';
    UNITABLE: ARRAY [UNITNUM] OF (*0 NOT USED*)
                RECORD
                  UVID: VID;    (*VOLUME ID FOR UNIT*)
                  CASE UISBLKD: BOOLEAN OF
                    TRUE: (UEOVBLK: INTEGER)
                END (*UNITABLE*) ;
    FILENAME : FILE_TABLE;
    
(*-------------------------------------------------------------------------*)
(* SYSTEM PROCEDURE FORWARD DECLARATIONS *)
(* THESE ARE ADDRESSED BY OBJECT CODE... *)
(*  DO NOT MOVE WITHOUT CAREFUL THOUGHT  *)

PROCEDURE EXECERROR;
  FORWARD;
PROCEDURE FINIT(VAR F: FIB; WINDOW: WINDOWP; RECWORDS: INTEGER);
  FORWARD;
PROCEDURE FRESET(VAR F: FIB);
  FORWARD;
PROCEDURE FOPEN(VAR F: FIB; VAR FTITLE: STRING;
                FOPENOLD: BOOLEAN; JUNK: FIBP);
  FORWARD;
PROCEDURE FCLOSE(VAR F: FIB; FTYPE: CLOSETYPE);
  FORWARD;
PROCEDURE FGET(VAR F: FIB);
  FORWARD;
PROCEDURE FPUT(VAR F: FIB);
  FORWARD;
PROCEDURE XSEEK;
  FORWARD;
FUNCTION FEOF(VAR F: FIB): BOOLEAN;
  FORWARD;
FUNCTION FEOLN(VAR F: FIB): BOOLEAN;
  FORWARD;
PROCEDURE FREADINT(VAR F: FIB; VAR I: INTEGER);
  FORWARD;
PROCEDURE FWRITEINT(VAR F: FIB; I,RLENG: INTEGER);
  FORWARD;
PROCEDURE XREADREAL;
  FORWARD;
PROCEDURE XWRITEREAL;
  FORWARD;
PROCEDURE FREADCHAR(VAR F: FIB; VAR CH: CHAR);
  FORWARD;
PROCEDURE FWRITECHAR(VAR F: FIB; CH: CHAR; RLENG: INTEGER);
  FORWARD;
PROCEDURE FREADSTRING(VAR F: FIB; VAR S: STRING; SLENG: INTEGER);
  FORWARD;
PROCEDURE FWRITESTRING(VAR F: FIB; VAR S: STRING; RLENG: INTEGER);
  FORWARD;
PROCEDURE FWRITEBYTES(VAR F: FIB; VAR A: WINDOW; RLENG,ALENG: INTEGER);
  FORWARD;
PROCEDURE FREADLN(VAR F: FIB);
  FORWARD;
PROCEDURE FWRITELN(VAR F: FIB);
  FORWARD;
PROCEDURE SCONCAT(VAR DEST,SRC: STRING; DESTLENG: INTEGER);
  FORWARD;
PROCEDURE SINSERT(VAR SRC,DEST: STRING; DESTLENG,INSINX: INTEGER);
  FORWARD;
PROCEDURE SCOPY(VAR SRC,DEST: STRING; SRCINX,COPYLENG: INTEGER);
  FORWARD;
PROCEDURE SDELETE(VAR DEST: STRING; DELINX,DELLENG: INTEGER);
  FORWARD;
FUNCTION SPOS(VAR TARGET,SRC: STRING): INTEGER;
  FORWARD;
FUNCTION FBLOCKIO(VAR F: FIB; VAR A: WINDOW; I: INTEGER;
                  NBLOCKS,RBLOCK: INTEGER; DOREAD: BOOLEAN): INTEGER;
  FORWARD;
PROCEDURE FGOTOXY(X,Y: INTEGER);
  FORWARD;

(* NON FIXED FORWARD DECLARATIONS *)

FUNCTION VOLSEARCH(VAR FVID: VID; LOOKHARD: BOOLEAN;
                   VAR FDIR: DIRP): UNITNUM;
  FORWARD;
PROCEDURE WRITEDIR(FUNIT: UNITNUM; FDIR: DIRP);
  FORWARD;
FUNCTION DIRSEARCH(VAR FTID: TID; FINDPERM: BOOLEAN; FDIR: DIRP): DIRRANGE;
  FORWARD;
FUNCTION SCANTITLE(FTITLE: STRING; VAR FVID: VID; VAR FTID: TID;
                   VAR FSEGS: INTEGER; VAR FKIND: FILEKIND): BOOLEAN;
  FORWARD;
PROCEDURE DELENTRY(FINX: DIRRANGE; FDIR: DIRP);
  FORWARD;
PROCEDURE INSENTRY(VAR FENTRY: DIRENTRY; FINX: DIRRANGE; FDIR: DIRP);
  FORWARD;
PROCEDURE HOMECURSOR;
  FORWARD;
PROCEDURE CLEARSCREEN;
  FORWARD;
PROCEDURE CLEARLINE;
  FORWARD;
PROCEDURE PROMPT;
  FORWARD;
FUNCTION SPACEWAIT(FLUSH: BOOLEAN): BOOLEAN;
  FORWARD;
FUNCTION GETCHAR(FLUSH: BOOLEAN): CHAR;
  FORWARD;
FUNCTION FETCHDIR(FUNIT:UNITNUM) : BOOLEAN;
  FORWARD;
PROCEDURE COMMAND;
  FORWARD;


